<?php

namespace App\Helpers;

use App\Services\SysFileService;
use Illuminate\Http\Request;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

trait UploadHelper
{
    /**
     * 百度编辑器文件上传
     * @param Request $request
     */
    public function ueditorUpload(Request $request)
    {
        // Make sure file is not cached (as it happens for example on iOS devices)
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");

        ini_set('upload_max_filesize', '100m');
        $action = $request->get('action');
        switch ($action) {
            case 'config'://编辑器配置
                $configPath = public_path() . '/vendor/neditor/php/config.json';
                $configData = file_get_contents($configPath);
                $configData = preg_replace("/\/\*[\s\S]+?\*\//", "", $configData);
                $configData = json_decode($configData, true);;
                return \Response::json($configData);
                break;
            case 'uploadimage'://上传图片
            case 'uploadvideo'://上传视频
            case 'uploadfile'://上传文件
                try {
                    //是否有文件上传急上传文件有效性
                    if ($request->hasFile('upfile') && $request->file('upfile')->isValid()) {
                        $file = $request->file('upfile');
                        $fileInfo = [
                            'disk_name' => 'sfy',
                            'origin_name' => $file->getClientOriginalName(),//原始文件名
                            'file_ext' => $file->extension(),//扩展名
                            'file_size' => $file->getClientSize(),//文件大小
                            'file_type' => 'image',//文件类别
                        ];
                        if ($action == 'uploadimage') {
                            $fileInfo['file_type'] = 'image';
                        } else if ($action == 'uploadvideo') {
                            $fileInfo['file_type'] = 'video';
                        } else {
                            $fileInfo['file_type'] = 'file';
                        }
                        $savePath = 'upload' . DIRECTORY_SEPARATOR . date('Ymd');
                        $fileInfo['new_name'] = $file->hashName();
                        //保存到文件目录
                        $localFilePath = $file->storeAs($savePath, $fileInfo['new_name']);
                        $fileInfo['file_path'] = $localFilePath;
                        //远程文件上传
                        $uploadInfo = (new SysFileService())->uploadFile($file->getRealPath(), $fileInfo['origin_name']);
                        $fileInfo['view_url'] = $uploadInfo['url'];
                        //文件真实路径
                        //\Storage::disk($fileInfo['disk_name'])->put($fileInfo['file_path'], fopen($file->getRealPath(),'r+'));
                        //$fileInfo['view_url'] = (string)\Storage::disk('qiniu')->getDriver()->downloadUrl($fileInfo['file_path'], 'custom');
                        //保存文件数据
                        (new SysFileService())->saveFileInfo($fileInfo);
                        return \Response::json(['state' => 'SUCCESS', 'url' => $fileInfo['view_url'], 'title' => $fileInfo['new_name'], 'original' => $fileInfo['origin_name']]);
                    } else {
                        throw new \Exception('请选择上传文件');
                    }
                } catch (\Exception $e) {
                    return \Response::json(['state' => $e->getMessage()]);
                }
                break;
            case 'uploadscrawl'://上传涂鸦
                try {
                    //是否有文件上传急上传文件有效性
                    if ($request->has('upfile')) {
                        $fileContent = base64_decode($request->post('upfile'));
                        $fileInfo = [
                            'disk_name' => 'sfy',
                            'origin_name' => 'scrawl.png',//原始文件名
                            'file_ext' => 'png',//扩展名
                            'file_size' => 0,//文件大小
                            'file_type' => 'image',//文件类别
                        ];
                        $savePath = 'upload' . DIRECTORY_SEPARATOR . date('Ymd');
                        $fileInfo['new_name'] = date("YmdHis") . uniqid() . '.' . $fileInfo['file_ext'];
                        //保存到文件目录
                        $fileInfo['file_path'] = $savePath . DIRECTORY_SEPARATOR . $fileInfo['new_name'];
                        //保存到本地
                        $localDisk = \Storage::disk('local');
                        $localDisk->put($fileInfo['file_path'], $fileContent);
                        //上传到索菲亚内部文件服务地址
                        $fileRealPath = $localDisk->path($fileInfo['file_path']);
                        $uploadInfo = (new SysFileService())->uploadFile($fileRealPath, $fileInfo['origin_name']);
                        $fileInfo['view_url'] = $uploadInfo['url'];
                        $fileInfo['file_size'] = $uploadInfo['size'];
                        //文件真实路径
                        //$disk = \Storage::disk($fileInfo['disk_name']);
                        //$disk->put($fileInfo['file_path'], $fileContent);
                        //文件大小
                        //$fileInfo['file_size'] = $disk->size($fileInfo['file_path']);
                        //$fileInfo['view_url'] = (string)\Storage::disk('qiniu')->getDriver()->downloadUrl($fileInfo['file_path'], 'custom');
                        //保存文件数据
                        (new SysFileService())->saveFileInfo($fileInfo);
                        return \Response::json(['state' => 'SUCCESS', 'url' => $fileInfo['view_url'], 'title' => $fileInfo['new_name'], 'original' => $fileInfo['origin_name']]);
                    } else {
                        throw new \Exception('请选择上传文件');
                    }
                } catch (\Exception $e) {
                    return \Response::json(['state' => $e->getMessage()]);
                }
                break;
            case 'catchimage'://抓取远程文件
                $list = [];
                if ($request->has('source')) {
                    $source = $request->post('source');
                    if (!empty($source)) {
                        foreach ($source as $remoteUrl) {
                            try {
                                //保存远程文件到本地
                                $localFileInfo = (new SysFileService())->saveRemoteFile($remoteUrl);
                                $fileInfo = [
                                    'disk_name' => 'sfy',
                                    'file_type' => $localFileInfo['file_type'],
                                    'file_ext' => $localFileInfo['file_ext'],
                                    'origin_name' => $localFileInfo['origin_name'],
                                    'new_name' => $localFileInfo['new_name'],
                                    'file_path' => $localFileInfo['file_path'],
                                ];
                                //上传到索菲亚内部文件服务地址
                                $fileRealPath = \Storage::disk('local')->path($fileInfo['file_path']);
                                $uploadInfo = (new SysFileService())->uploadFile($fileRealPath, $fileInfo['origin_name']);
                                $fileInfo['view_url'] = $uploadInfo['url'];
                                $fileInfo['file_size'] = $uploadInfo['size'];
                                //获取文件绝对路径
                                //$fileRealPath = \Storage::disk('local')->path($fileInfo['file_path']);
                                //$disk = \Storage::disk($fileInfo['disk_name']);
                                //$disk->put($fileInfo['file_path'], fopen($fileRealPath,'r+'));
                                //文件大小
                                //$fileInfo['file_size'] = $disk->size($fileInfo['file_path']);
                                //$fileInfo['view_url'] = (string)\Storage::disk('qiniu')->getDriver()->downloadUrl($fileInfo['file_path'], 'custom');
                                //保存文件数据
                                (new SysFileService())->saveFileInfo($fileInfo);
                                $list[] = [
                                    'url' => $fileInfo['view_url'],
                                    'source' => $remoteUrl,
                                    'state' => 'SUCCESS',
                                ];
                            } catch (\Exception $e) {
                                $list[] = [
                                    'url' => '',
                                    'source' => $remoteUrl,
                                    'state' => $e->getMessage(),
                                ];
                            }
                        }
                    }
                }
                return \Response::json(['state' => 'SUCCESS', 'list' => $list]);
                break;
            case 'listimage'://列出图片
            case 'listfile'://列出文件
                $size = $request->get('size', 20);
                $start = $request->get('start', 0);
                $page = ($start / $size) + 1;
                //文件列表
                $query = \App\Models\SysFile::select('*');
                if ($action == 'listimage') {
                    $query->where('file_type', SysFileService::TYPE_IMAGE);
                } elseif ($action == 'listfile') {
                    $query->where('file_type', SysFileService::TYPE_FILE);
                }
                $row = $query->paginate($size, ['*'], 'page', $page);
                $row = $row->toArray();
                $list = [];
                if ($row['data']) {
                    foreach ($row['data'] as $v) {
                        $list[] = ['url' => $v['view_url']];
                    }
                }
                return \Response::json(['state' => 'SUCCESS', 'list' => $list, 'start' => $start, 'total' => $row['total']]);
                break;
            default:
                return \Response::json(['state' => '请求地址出错']);
        }
    }

    /**
     * webupload上传组件上传方法
     * @param Request $request
     */
    public function webUpload(Request $request)
    {
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: ".gmdate("D, d M Y H:i:s") ." GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");
        try {
            $num = $request->get('chunk', 0);
            $count = $request->get('chunks',0);
            //文件类型
            $fileType = $request->get('fileType', 'file');
            $file = $request->file('file');
            //获取原文件名
            $originalName = $file->getClientOriginalName();
            //扩展名
            $ext = $file->getClientOriginalExtension();
            //文件类型
            $type = $file->getClientMimeType();
            //临时绝对路径
            $realPath = $file->getRealPath();
            $savePath = 'upload' . DIRECTORY_SEPARATOR . date('Ymd');
            if($num == $count){
                //直接保存
                $newFileName = $file->hashName();
                $newFilePath = $file->storeAs($savePath, $newFileName);
                $newFileRealPath = \Storage::disk('local')->path($newFilePath);
            }else{
                //分片临时文件名
                $tmpFileName = md5($originalName).'-'.($num+1).'.tmp';
                //上传目录
                $tempPathName = 'tmp/'.$tmpFileName;
                //保存临时文件
                $bool = \Storage::disk('local')->put($tempPathName, file_get_contents($realPath));
                //当分片上传完时 合并
                if(($num+1) == $count){
                    //最后合成后的名字及路径
                    $newFileName = date("YmdHis") . uniqid() .'.'.$ext;
                    $newFilePath = $savePath.'/'. $newFileName;
                    //转换为绝对路径
                    $newFileRealPath = \Storage::disk('local')->path($newFilePath);
                    //打开文件
                    $fp = fopen($newFileRealPath,"ab");
                    //循环读取临时文件，写入最终文件
                    for($i=0;$i<$count;$i++){
                        //临时文件路径及名称
                        $tmpFiles = 'tmp/'.md5($originalName).'-'.($i+1).'.tmp';
                        //转换为绝对路径
                        $tmpFiles = \Storage::disk('local')->path($tmpFiles);
                        //打开临时文件
                        $handle = fopen($tmpFiles,"rb");
                        //读取临时文件 写入最终文件
                        fwrite($fp, fread($handle, filesize($tmpFiles)));
                        //关闭句柄 不关闭删除文件会出现没有权限
                        fclose($handle);
                        //删除临时文件
                        unlink($tmpFiles);
                    }
                    //关闭句柄
                    fclose($fp);
                }else{
                    return $this->showMsg('success', '上传分片成功');
                }
            }
            $fileInfo = [
                'disk_name' => 'sfy',
                'origin_name' => $originalName,//原始文件名
                'file_ext' => $ext,//扩展名
                'file_size' => $file->getClientSize(),//文件大小
                'file_type' => $fileType,//文件类别
                'new_name' => $newFileName,//新文件名
                'file_path' => $newFilePath,//新文件目录，相对目录
            ];
            //远程文件上传
            $uploadInfo = (new SysFileService())->uploadFile($newFileRealPath, $originalName);
            $fileInfo['view_url'] = $uploadInfo['url'];
            $fileInfo['file_size'] = $uploadInfo['size'];
            //上传到七牛云
            //$disk = \Storage::disk($fileInfo['disk_name']);
            //$disk->put($fileInfo['file_path'], fopen($newFileRealPath,'r+'));
            //$fileInfo['view_url'] = (string) $disk->getDriver()->downloadUrl($fileInfo['file_path'], 'custom');
            //$fileInfo['file_size'] = $disk->getSize($fileInfo['file_path']);
            //保存文件数据
            (new SysFileService())->saveFileInfo($fileInfo);

            return $this->showMsg('success', '上传成功', $fileInfo);
        } catch (\Exception $e) {
            return $this->showMsg('error', $e->getMessage());
        }

    }
}